﻿#include "Game.h"

/*
 * Function: Game
 * Summary: 有参构造函数，用于修改棋盘数据，给AI端实例化
 * Input: int** arr为外部传入二维数组的指针
 * Output: void
 */
Game::Game(int** arr)
{
    int** sourceData=data.getArray();
    for(int i=0;i<4;++i)
    {
        for(int j=0;j<4;++j)
        {
            sourceData[i][j]=arr[i][j];
        }
    }
    comboNumber=0;
}

/*
 * Function: Game
 * Summary: 无参构造函数，给控制器实例化
 * Input: void
 * Output: void
 */
Game::Game()
{
    comboNumber=0;
}

/*
 * Function: moveAI
 * Summary: 接收方向指示后进行相应的数据操作，AI端调用
 * Input: directionID为方向序号
 * Output: 返回值为移动是否成功的标志
 */
bool Game::moveAI(int directionID)
{
    //1-上，2-下，3-左，4-右
    switch (directionID) {
    case 1:
        return responseMoveAI(up);
        break;
    case 2:
        return responseMoveAI(down);
        break;
    case 3:
        return responseMoveAI(left);
        break;
    case 4:
        return responseMoveAI(right);
        break;
    default:
        return false;
        break;
    }
}

/*
 * Function: move
 * Summary: 接收方向指示后进行相应的数据操作，控制端调用
 * Input: directionID为方向序号
 * Output: 返回值为移动是否成功的标志
 */
bool Game::move(int directionID)
{
    //1-上，2-下，3-左，4-右
    switch (directionID) {
    case 1:
        return responseMove(up);
        break;
    case 2:
        return responseMove(down);
        break;
    case 3:
        return responseMove(left);
        break;
    case 4:
        return responseMove(right);
        break;
    default:
        return false;
        break;
    }
}

/*
 * Function: getData
 * Summary: 获取棋盘数据
 * Input: void
 * Output: 返回值为棋盘数据
 */
int** Game::getData()
{
    return data.getArray();
}

/*
 * Function: gameOver
 * Summary: 遍历棋盘数据，判断游戏是否结束
 * Input: void
 * Output: 返回值为游戏是否结束的标志，0-游戏未结束，1-游戏结束
 */
bool Game::gameOver()
{
    int** arr=data.getArray();
    for(int i=0;i<4;++i)
    {
        for(int j=0;j<3;++j)
        {
            if((arr[i][j]==0)||(arr[i][j]==arr[i][j+1]))
            {
                return false;
            }
        }
    }

    for(int i=3;i>=0;--i)
    {
        for(int j=0;j<3;++j)
        {
            if((arr[j][i]==0)||(arr[j][i]==arr[j+1][i]))
            {
                return false;
            }
        }
    }

    if(arr[3][3]==0)
    {
        return false;
    }

    return true;
}

/*
 * Function: getCurrentScore
 * Summary: 获取当前的总得分
 * Input: void
 * Output: 返回值为当前的总得分
 */
int Game::getCurrentScore()
{
    return data.getScore();
}

/*
 * Function: getOptimalScore
 * Summary: 获取目前为止的最佳分数
 * Input: void
 * Output: 返回值为目前为止的最佳分数
 */
int Game::getOptimalScore()
{
    return data.getBestScore();
}

/*
 * Function: setOptimalScore
 * Summary: 当打开App时，由控制器调用该函数，设置最佳分数
 * Input: optimalScore为从保存文件中读取的数据
 * Output: 返回值为设置是否成功的标志
 */
bool Game::setOptimalScore(int optimalScore)
{
    if(data.setBestScore(optimalScore))
    {
        return true;
    }else {
        return false;
    }
}

/*
 * Function: restart
 * Summary: 清除棋盘数据，清除当前总分数，不清除最佳分数，重新开始游戏，随机生成两个数字
 * Input: void
 * Output: 返回值为重新开始游戏是否成功的标志
 */
bool Game::restart()
{
    comboNumber=0;
    if(data.cleanData())
    {
        if(data.generateNums())
        {
            return true;
        }
    }

    return false;
}

/*
 * Function: getComboNumber
 * Summary: 获取成员变量comboNumber的值
 * Input: void
 * Output: 返回值为成员变量comboNumber的值
 */
int Game::getComboNumber()
{
    return comboNumber;
}

/*
 * Function: passGame
 * Summary: 判断是否通过游戏，即凑成2048
 * Input: void
 * Output: 返回值为游戏是否通过的标志，0-游戏未通过，1-游戏通过
 */
bool Game::passGame()
{
    int** arr=data.getArray();
    for(int i=0;i<4;++i)
    {
        for(int j=0;j<4;++j)
        {
            if(arr[i][j]==2048)
            {
                return true;
            }
        }
    }
    return false;
}

/*
 * Function: responseMoveAI
 * Summary: 利用多态响应方向的移动，进行数据操作，该接口不暴露
 * Input: 方向实例对象
 * Output: 返回值为响应是否成功的标志
 */
bool Game::responseMoveAI(Direction& direction)
{
    //获取单次合并所获得的分数
    int newScore=direction.merge(data.getArray());

    //如果移动了但没有任何数字合并，连招次数设置为0
    if((newScore==0)&&(direction.getDataChanged()==1))
    {
        comboNumber=0;
    }else {
        data.addScore(newScore);
        comboNumber=comboNumber+direction.getCombo();
    }

    if(direction.getDataChanged()==1)
    {
        return true;
    }else {
        return false;
    }
}

/*
 * Function: responseMove
 * Summary: 利用多态响应方向的移动，进行数据操作，该接口不暴露
 * Input: 方向实例对象
 * Output: 返回值为响应是否成功的标志
 */
bool Game::responseMove(Direction& direction)
{
    //获取单次合并所获得的分数
    int newScore=direction.merge(data.getArray());

    //如果移动了但没有任何数字合并，连招次数设置为0
    if((newScore==0)&&(direction.getDataChanged()==1))
    {
        comboNumber=0;
    }else {
        data.addScore(newScore);
        comboNumber=comboNumber+direction.getCombo();
    }

    if(direction.getDataChanged()==1)
    {
        direction.generateNum(data.getArray());
        return true;
    }else {
        return false;
    }
}
